package cn.yl.fxboot.application.action;

import java.io.File;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.yl.fxboot.application.service.Common;
import cn.yl.fxboot.application.service.DecodeVideo;
import cn.yl.fxboot.application.service.DouyinHelper;
import cn.yl.fxboot.application.service.Script;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.concurrent.Worker.State;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.DirectoryChooser;

public class SingleActions {

	public EventHandler<ActionEvent> singleAddrBtnHandler(TextField node) {
		return new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				DirectoryChooser dirChooser = new DirectoryChooser();
				dirChooser.setTitle("选择导出文件夹");
				// dirChooser.setInitialDirectory(new File("D:\\Documents"));
				File dir = dirChooser.showDialog(node.getScene().getWindow());
				if (dir != null) {
					node.setText(dir.getPath());
				}
			}
		};
	}

	public EventHandler<ActionEvent> singleStartBtnHandler(TextArea singleUrl_Area, TextField singleAddr_TF) {
		return new EventHandler<ActionEvent>() {
			@Override
			public void handle(ActionEvent event) {
				Task<Void> t = new Task<Void>() {

					@Override
					protected void running() {
						updateMessage("开始!");
					}

					@Override
					protected void succeeded() {
						updateMessage("结束!");
					}

					@Override
					protected void cancelled() {
						updateMessage("被中断!");
					}

					@Override
					protected void failed() {
						updateMessage("error:失败!");
					}

					@Override
					protected Void call() throws Exception {
						String errMsg;
						String url = singleUrl_Area.getText();
						String addr = singleAddr_TF.getText();
						if (StrUtil.isBlank(url)) {
							errMsg = "error:请输入链接内容";
							updateMessage(errMsg);
							return null;
						}

						if (StrUtil.isBlank(addr)) {
							errMsg = "error:请先选择导出文件夹";
							updateMessage(errMsg);
							return null;
						}
						errMsg = "正在获取视频...";
						updateMessage(errMsg);
						List<String> list = ReUtil.findAllGroup0(Common.RE_URLS, url);
						updateMessage("获取到"+list.size()+"条视频源");
						for(int j=0;j<list.size();j++) {
							int i = j+1;
							try {
								Optional<DecodeVideo> videoOpt = DouyinHelper.decode(list.get(j));
								int retry = 0;
								while(retry < 4 && (!videoOpt.isPresent() || StrUtil.isBlank(videoOpt.get().getPlayAddr()))) {
									videoOpt = DouyinHelper.decode(list.get(j));
									retry++;
								}
								if (videoOpt.isPresent()) {
									DecodeVideo video = videoOpt.get();
									errMsg = "视频获取成功..正在下载第"+i+"个视频...";
									updateMessage(errMsg);
									CheckBox cb = (CheckBox) singleAddr_TF.getScene().lookup("#singleOnlyVideo");
									if(cb.isSelected()) {
										String dir = DouyinHelper.downloadOnlyVideoSingle(video, addr);
										errMsg = "第"+i+"个视频下载完成,文件位置: " + dir;
										updateMessage(errMsg);
									}else {
										String dir = DouyinHelper.download(video, addr);
										errMsg = "第"+i+"个视频下载完成,文件位置: " + dir;
										updateMessage(errMsg);
									}
								} else {
									errMsg = "error:没有对应的视频";
									updateMessage(errMsg);
								}

							} catch (Exception e) {
								errMsg = "error:第"+i+"个视频下载失败,请求链接错误";
								updateMessage(errMsg);
								errMsg = null;
								e.printStackTrace();
							}
							errMsg = null;
						}
						return null;
					}
				};
				String taskId = "任务 " + RandomUtil.randomString(4)+" --> " ;
				t.messageProperty().addListener(new ChangeListener<String>() {
					@Override
					public void changed(ObservableValue<? extends String> observable, String oldValue,
							String newValue) {
						MsgPaneActions.doLog(taskId + newValue);
					}
				});

				new Thread(t).start();
			}
		};
	}
	
	private void getUserVideos(String url, WebView wv,String workId) {
		WebEngine we = wv.getEngine();
		Worker<Void> wk = we.getLoadWorker();
		wk.stateProperty().addListener(new ChangeListener<State>() {

			@Override
			public void changed(ObservableValue<? extends State> observable, State oldValue, State newValue) {
				if (State.SUCCEEDED.equals(newValue)) {
					Task<Void> t = new Task<Void>() {

						@Override
						protected Void call() throws Exception {
							System.out.println((we.getLocation()));
							String location = we.getLocation();
							String[] mainOri = location.split("?");
							String origin = mainOri[0];
							String param = mainOri[1];
							String[] params = param.split("&");
							String userId = "";
							String userCode= "";
							for(String s : params) {
								if(s.contains("u_code")) {
									userCode = s.split("=")[1];
								}
								if(s.contains("sec_uid")) {
									userId = s.split("=")[1];
								}
							}
							String dytk = "";
							Document doc = (Document) we.getDocument();
							Elements scriptElements = doc.getElementsByTag("script");
							for (Element elements : scriptElements) {
								 if (StrUtil.containsAny(elements.toString(), "douyin_falcon:page/reflow_video/index")) {
						                String text = StrUtil.removeAllLineBreaks(StrUtil.removeAll(StrUtil.subBetween(elements.toString(), "({", "})"), '"')).trim();
						                List<String> keys = StrUtil.splitTrim(text, ",");
						                if (CollUtil.isNotEmpty(keys)) {
						                    HashMap<String, String> scriptParams = MapUtil.newHashMap();
						                    for (String key : keys) {
						                        List<String> list = StrUtil.splitTrim(key, ":");
						                        scriptParams.put(list.get(0), list.get(1));
						                    }
						                    dytk = scriptParams.get("dytk");
						                }
								 }
							}
							
							String str = (String) we.executeScript(Script.genSignScript(""));
							String sign = Script.videoListUrl(userId,str, "");
							Map<String, String> headers = new HashMap<>();
							headers.put("accept", "application/json");
							headers.put("sec-fetch-mode", "cors");
							headers.put("sec-fetch-site", "same-origin");
							Timestamp ts = new Timestamp(System.currentTimeMillis());
							headers.put("referer",
									origin+"?u_code="+userCode+"&sec_uid="+userId+"&timestamp="
											+ ts
											+ "&utm_source=copy&utm_campaign=client_share&utm_medium=android&share_app_name=douyin");
							HttpResponse resp = HttpRequest.get(sign).addHeaders(headers).execute();
							System.out.println(resp);
							return null;
						}
					};
					t.messageProperty().addListener(new ChangeListener<String>() {
						@Override
						public void changed(ObservableValue<? extends String> observable, String oldValue,
								String newValue) {
							MsgPaneActions.doLog(workId+" --> "+newValue);
						}
					});
				}
			}

		});
		Platform.runLater(() -> {
			we.load(url);
		});
	}
}
